﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tracy.DataServices;
using SharedLib.XmlDataModel;
using Tracy.DataModel;
using System.Xml;
using System.Collections.Specialized;
using SharedLib.Helpers;
using Tracy.Properties;
using Microsoft.Practices.Unity;

namespace Tracy.BasicServices
{
    public class DownloadManager : FilterItemProvider<Tracy.BasicServices.DownloadManager.DownloaderSetting>
    {
        public class DownloaderSetting : XmlDataModelWithAttributes, IHasName
        {
            /// <summary>
            /// Name of the Downloader
            /// </summary>
            public string Name
            {
                get { return Attributes["name"]; }
                set { Attributes["name"] = value; }
            }

            public string ClassName
            {
                get { return Properties ["class-name"]; }
                set { Properties["class-name"] = value; }
            }

            public DownloaderSetting() : base() { }
            public DownloaderSetting(XmlNode node) : base(node) { }

            public override string RootNodeName
            {
                get
                {
                    return "downloader";
                }
            }
        }

        private Dictionary<string, IDownloadAdapter> _downloaderDic;
        //Caches the instances of download adapters
        private Dictionary<string, IDownloadAdapter> DownloaderDic
        {
            get {
                if (_downloaderDic == null) _downloaderDic = InitDownloaders();
                return _downloaderDic; 
            }
        }

        private bool _isAutoDownloadMode = false;

        public bool IsAutoDownloadMode
        {
            get { return _isAutoDownloadMode; }
            set { _isAutoDownloadMode = value; }
        }

        public DownloadManager()
            : base(@"Settings\Downloaders.xml", "downloaders/downloader")
        {
        }

        private Dictionary<string, IDownloadAdapter> InitDownloaders()
        {
            Dictionary<string, IDownloadAdapter> downloaderDic = new Dictionary<string, IDownloadAdapter>();
            foreach (XmlElement node in doc.SelectNodes(_itemXPath))
            {
                foreach (XmlElement typeNode in node.SelectNodes("resource-types/resource-type"))
                {
                    string type = XmlHelper.GetNodeValue(typeNode);
                    if (!downloaderDic.ContainsKey(type) || typeNode.GetAttribute("default") == "true")
                    {
                        string className = XmlHelper.GetNodeValue(node, "class-name");
                        IDownloadAdapter adapter = TracyFacade.Instance.DIContainer.Resolve<IDownloadAdapter>(className);
                        StringDictionary parameters = new StringDictionary();
                        foreach(XmlElement paramNode in node.SelectNodes("parameters/parameter"))
                        {
                            parameters.Add(paramNode.GetAttribute("key"), XmlHelper.GetNodeValue(paramNode));
                        }
                        adapter.Init(parameters);
                        if (adapter.IsResourceTypeSupported(type))
                        {
                            downloaderDic[type] = adapter;
                        }
                    }
                }
            }
            return downloaderDic;
        }

        //public void DisplayUI(string resourceType)
        //{
        //    IDownloadAdapter adapter = GetDownloader(resourceType);
        //    if (adapter != null)
        //    {
        //        adapter.DisplayUI();
        //    }
        //}

        private IDownloadAdapter GetDownloader(string resourceType)
        {
            //XmlNode node = doc.SelectSingleNode(_itemXPath + String.Format("[resource-types/resource-type='{0}' and resource-types/resource-type/@default='true']", resourceType));
            //if (node == null)
            //{
            //    node = doc.SelectSingleNode(_itemXPath + String.Format("[resource-types/resource-type='{0}']", resourceType));
            //}

            //if (node != null)
            //{
            //    DownloaderSetting setting = new DownloaderSetting(node);
            //    IDownloadAdapter rtn = TracyBus.Instance.RegisteredObjectService.CreateInstance<IDownloadAdapter>(setting.ClassName);
            //    return rtn;
            //}
            if (DownloaderDic.ContainsKey(resourceType))
            {
                IDownloadAdapter rtn = DownloaderDic[resourceType];
                return rtn;
            }
            return null;
        }

        public void DownloadResource(Resource resource)
        {
            IDownloadAdapter adapter = GetDownloader(resource.GetResourceType());
            if (adapter != null)
            {
                adapter.Download(resource, Tracy.Properties.Settings.Default.DefaultDownloadFolder);
            }
            //TODO: notify user if not supported
        }

        public string[] GetDownloadingFilePaths(MediaFile file)
        {
            if (file == null || file.Resource == null) return null;
            string fullPath = file.GetDownloadPath();
            if (string.IsNullOrEmpty(fullPath)) return null;

            string type = file.Resource.GetResourceType();
            if (DownloaderDic.ContainsKey(type))
            {
                string[] fileExts = DownloaderDic[type].GetTempFileExts(type);
                string[] rtn = new string[fileExts.Length];
                for (int i = 0; i < rtn.Length; i++)
                {
                    rtn[i] = fullPath + fileExts[i];
                }
                return rtn;
            }
            return null;
            
        }

        public string GetDownloadFolder(Resource res)
        {
            if (res == null) return Settings.Default.DefaultDownloadFolder;
            string type = res.GetResourceType();
            if (DownloaderDic.ContainsKey(type))
            {
                return DownloaderDic[type].GetTempDownloadFolder(Settings.Default.DefaultDownloadFolder);
            }
            return Settings.Default.DefaultDownloadFolder;
        }

        public string GetValidFileName(string filename, string type)
        {
            if (DownloaderDic.ContainsKey(type))
            {
                return DownloaderDic[type].GetValidFileName(filename);
            }
            return filename;
        }
    }
}
